#include "frame_pool_factory.h"
#include <iostream>
#include <thread>
using namespace std;

int main()
{
	size_t spliceSize = 64;
	size_t spliceCnt = 64;
	auto& ins = FramePoolFact::GetInstance();
	ins.CreatePool(spliceSize, spliceCnt, 0);
	cout << "------------ case 1 --------------" << endl;
	auto fptr = ins.BorrowFrame(50);
	ASSERT(fptr != nullptr);
	const char* a = "abcdefg";
	fptr->Assign((char*)a, strlen(a));
	cout << ins.Audit() << endl;
	ins.ReturnFrame(fptr);
	cout << ins.Audit() << endl;
	cout << "------------ case 2 --------------" << endl;
	std::vector<FramePtr> vec, vec2,vec3;
	ins.BorrowFrames(vec, 50, 50);
	cout << ins.Audit() << endl;
	ins.ReturnFrames(vec);
	cout << ins.Audit() << endl;
	cout << "------------ case 3 --------------" << endl;
	vec.clear();
	ins.CreatePool(spliceSize*2, spliceCnt, 1);
	cout << ins.Audit() << endl;
	ins.BorrowFrames(vec, 80, 100);
	cout << ins.Audit() << endl;
	ins.BorrowFrames(vec2, 80, 200);
	cout << ins.Audit() << endl;
	cout << vec2.size() << endl;
	ins.ReturnFrames(vec);
	cout << ins.Audit() << endl;
	ins.ReturnFrames(vec2);
	cout << ins.Audit() << endl;
	cout << "------------ case 4 --------------" << endl;
	ins.CreatePool(spliceCnt * 4, 64, 2);
	ins.BorrowFrames(vec3, 255, 200);
	cout << ins.Audit() << endl;
	cout << vec3.size() << endl;
	ins.ReturnFrames(vec3);
	cout << ins.Audit() << endl;

	cout << "------------ case 5 --------------" << endl;
	std::vector<FramePtr> vect1, vect2;
	std::thread t1([&ins, &vect1]()
		{
			int maxCnt = 100;
			while (maxCnt--)
			{
				vect1.push_back(ins.BorrowFrame(50));
				vect1.push_back(ins.BorrowFrame(100));
				vect1.push_back(ins.BorrowFrame(200));
				//cout << ins.Audit() << endl;
				ins.ReturnFrames(vect1);
			}
			cout << ins.Audit() << endl;
		});
	std::thread t2([&ins, &vect2]()
		{
			int maxCnt = 100;
			while (maxCnt--)
			{
				vect2.push_back(ins.BorrowFrame(50));
				vect2.push_back(ins.BorrowFrame(100));
				vect2.push_back(ins.BorrowFrame(200));
				//cout << ins.Audit() << endl;
				ins.ReturnFrames(vect2);
			}
			cout << ins.Audit() << endl;
		});
	t1.join();
	t2.join();
	cout << ins.Audit() << endl;
	cout << "------------ case 6 --------------" << endl;
	std::thread t3([&ins, &vect1]()
		{
			int maxCnt = 100;
			while (maxCnt--)
			{
				ins.BorrowFrames(vect1, 50, 50);
				ins.BorrowFrames(vect1, 100, 100);
				ins.BorrowFrames(vect1, 200, 200);
				//cout << ins.Audit() << endl;
				ins.ReturnFrames(vect1);
			}
			cout << ins.Audit() << endl;
		});
	std::thread t4([&ins, &vect2]()
		{
			int maxCnt = 100;
			while (maxCnt--)
			{
				ins.BorrowFrames(vect2, 50, 50);
				ins.BorrowFrames(vect2, 100, 100);
				ins.BorrowFrames(vect2, 200, 200);
				//cout << ins.Audit() << endl;
				ins.ReturnFrames(vect2);
			}
			cout << ins.Audit() << endl;
		});
	t3.join();
	t4.join();
	cout << ins.Audit() << endl;
	return 0;
}